home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 147 / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin / tools / ivl / src / clinearg.c < prev    next >
Text File  |  2000-04-08  |  6KB  |  212 lines

  1. /*
  2. *    (比較的汎用に組んだつもりの)コマンドライン解析処理
  3. *    インダイレクトファイルに対応してて、ファイル中の1単語を
  4. *    コマンドラインと同等に処理する
  5. *
  6. *    from Jun. 6,1999    by dummy.x.(with J-SAGA INDUSTY)
  7. */
  8. #include    <stdio.h>
  9. #include    <stdlib.h>
  10. #include    <string.h>
  11. #include    "comtype.h"
  12. #include    "easymac.h"
  13. #include    "dummyc.h"
  14. #include    "hufilec.h"
  15. #include    "clinearg.h"
  16.  
  17. /* 定数定義 */
  18. #define    RBUF_SIZE    1024    /* インダイレクトファイルの1行の最大バイト数 */
  19.  
  20. /* ファイル内変数 */
  21.     /* インダイレクトファイル関係 */
  22. static const char *indirect_fname_p;    /* ファイル名アドレス */
  23. static FILE *indirect_fp;        /* ファイルポインタ */
  24. static ulong indirect_arg_count;    /* 読み込み行数カウンタ */
  25.  
  26. /* 安易マクロ */
  27.     /* 今インダイレクトファイルからの引数取得中かを調べる */
  28. #define    is_from_indirect()    (indirect_fp != NULL)
  29.     /* エラーメッセージ表示
  30.     *    マクロ INDIRECT_MES_PRINT が定義されていると、
  31.     *    errprintf() による表示を行なう
  32.     */
  33. #if    defined(TEST_MAIN_DEFINE)    /* main() 定義時はエラーメッセージ表示する */
  34.  #define    INDIRECT_MES_PRINT
  35. #endif
  36. #if    defined(INDIRECT_MES_PRINT)
  37.  #define    ERR_PRINT(args)    errprintf##args
  38. #else
  39.  #define    ERR_PRINT(args)    /* 空置換 */
  40. #endif
  41.  
  42.  
  43. /* インダイレクトファイルからの引数取り込み準備を行なう
  44. *    返値:    成功すれば 0、何か問題があったら !0
  45. *    注記    * ファイル名は、ファイル内変数 indirect_fname_p に
  46. *        そのアドレスが設定されているものとして処理する。
  47. */
  48. static
  49. int ready_indirect(void)
  50. {
  51.     FILE *fp;
  52.  
  53.     /* とりあえずファイルオープンしてみる */
  54.     fp = fopen(indirect_fname_p, "r");
  55.     if (fp != NULL) {    /* 開けたら */
  56.         /* ファイル内変数にもろもろ設定 */
  57.         indirect_fp = fp;    /* ファイルポインタ */
  58.         indirect_arg_count = 0;    /* 行数カウンタ */
  59.     } else {
  60.         ERR_PRINT(("Error: インダイレクトファイル %s がオープンできませんでした。\n"
  61.             , indirect_fname_p));
  62.     }
  63.  
  64.     return (fp == NULL);
  65. }
  66.  
  67. /* インダイレクトファイルからの引数取り込みを終了する
  68. */
  69. static
  70. void finish_indirect(void)
  71. {
  72.     close_file(indirect_fp);    /* ファイルクローズ */
  73.     indirect_fname_p = NULL;    /* ファイル名アドレスをクリア */
  74.     indirect_arg_count = 0;        /* 行数カウンタクリア */
  75. }
  76.  
  77. /* インダイレクトファイルから引数を一つ取り込む
  78. *    返値:    成功すれば引数を取り込んだメモリのアドレス
  79. *        取り込みに失敗したか、EOF になったら NULL
  80. *    注記    * インダイレクトファイルは、「1行=1引数」という単純な
  81. *        形式にのみ対応している。
  82. *        * インダイレクトファイルの1行のバイト数は RBUF_SIZE に
  83. *        制限される。
  84. #if    defined(INDIRECT_ARG_ALLOCATE)
  85. *        * 成功した場合、malloc() によって確保したメモリに引数を
  86. *        取り込む。
  87. #else    defined(INDIRECT_ARG_ALLOCATE)
  88. *        * 成功した場合の返値は、この関数内部の static 配列の
  89. *        アドレスである。
  90. #endif    defined(INDIRECT_ARG_ALLOCATE)
  91. */
  92. static
  93. char *getarg_from_indirect(void)
  94. {
  95.     static char rbuf[RBUF_SIZE];
  96.  
  97.     /* まだファイルからの取り込み準備ができてなければ準備する */
  98.     if (!is_from_indirect()) {
  99.         if (ready_indirect() != 0) {    /* 準備に失敗 */
  100.             return NULL;    /* 失敗として即座に返る */
  101.         }
  102.     }
  103.  
  104.     /* 1行読み込む */
  105.     while (fgetsnn(rbuf, RBUF_SIZE, indirect_fp) != NULL) {    /* 1行読み込む */
  106.         /* それが有効な行か調べる */
  107.         if (!is_null_str(rbuf)                    /* 空行ではない */
  108.          && (strchr(CLINEARG_INDIRECT_FILE_CMNT_CHRS, rbuf[0]) == NULL)    /* コメント行でもない */
  109.         ) {
  110.             /* 有効な行だった */
  111. #if    defined(INDIRECT_ARG_ALLOCATE)
  112.             /* メモリ上に複製を作り、そのアドレスを返す */
  113.             char *result = strdup(rbuf);
  114.  
  115.             indirect_arg_count++;    /* 引数個数計上 */
  116.  
  117.             if (result == NULL) {    /* 複製失敗 */
  118.                 ERR_PRINT(("インダイレクトファイル %s の"
  119.                         " %d 個目の引数を格納する\n"
  120.                     , indirect_fname_p, indirect_arg_count));
  121.                 ERR_PRINT(("メモリが確保できませんでした。\n"));
  122.             }
  123.             return result;
  124.  
  125. #else    /* defined(INDIRECT_ARG_ALLOCATE) */
  126.             /* 読み込みバッファのアドレスをそのまま返す */
  127.             return rbuf;
  128.  
  129. #endif    /* defined(INDIRECT_ARG_ALLOCATE) */
  130.         }
  131.     }
  132.  
  133.     /* 読み込みで NULL になってたら */
  134.     if (ferror(indirect_fp)) {    /* エラーだった場合 */
  135.         /* エラーメッセージ表示 */
  136.         ERR_PRINT(("インダイレクトファイル %s から %d 個目の引数を読み込む時に\n"
  137.             , indirect_fname_p, indirect_arg_count));
  138.         ERR_PRINT(("エラーが発生しました。\n"));
  139.     }
  140.     finish_indirect();    /* ファイルからの取り込みを終了 */
  141.     return NULL;
  142. }
  143.  
  144. /* コマンドライン引数を一つ取得する
  145. *    引数:    argvp    - コマンドライン引数テーブルアドレス格納変数アドレス
  146. *    返値:    コマンドライン引数アドレス(=NULL:既に最後に達している)
  147. *        (*argvp)    - 次に参照するコマンドライン引数テーブルアドレス
  148. */
  149. char *get_cmdline_arg(char ***argvp)
  150. {
  151.     char *result;
  152.     const int ifoptlen = strlen(CLINEARG_INDIRECT_FILE_OPT_STR);
  153.     char **argv = *argvp;
  154.  
  155.     if (!is_from_indirect()) {    /* コマンドラインを見ている */
  156.         result = *argv++;    /* 引数アドレスを一つ取る */
  157.  
  158.         /* それがインダイレクトファイル指定オプションだったらそれ相応の処理をする */
  159.         if ((result != NULL)
  160.          && (memcmp(result, CLINEARG_INDIRECT_FILE_OPT_STR, ifoptlen) == 0)
  161.         ) {                /* インダイレクトファイルオプションだった */
  162.             /* ファイル名アドレスを設定 */
  163.             indirect_fname_p = result + ifoptlen;
  164.             /* ファイルから引数を一つ取る */
  165.             result = getarg_from_indirect();
  166.             if (result == NULL) {        /* 取れなかったら */
  167.                 result = *argv++;    /* 無視してコマンドラインでの次の引数を返す */
  168.             }
  169.         }
  170.     } else {            /* インダイレクトファイル検索中 */
  171.         result = getarg_from_indirect();    /* ファイルから引数を一つ取る */
  172.         if (result == NULL) {
  173.             result = *argv++;
  174.         }
  175.     }
  176.  
  177.     /* テーブル参照位置更新 */
  178.     *argvp = argv;
  179.  
  180.     return result;
  181. }
  182.  
  183.  
  184. #if    defined(TEST_MAIN_DEFINE)
  185. /* テスト用メイン関数
  186. *    コマンドライン引数をだらだらと表示する
  187. */
  188. int main(int argc, char **argv)
  189. {
  190.     int i;
  191.     const char *argp;
  192.     char ***argvp = &argv;
  193.  
  194.     /* NULL に出会うまでループ */
  195.     (*argvp)++;    /* argv[0]を飛ばす */
  196.     i = 1;        /* 引数数カウンタ初期化 */
  197.     while ((argp = get_cmdline_arg(argvp)) != NULL) {
  198.         printf("%4d:[%s]\n", i, argp);    /* 番号と内容表示 */
  199.         i++;                /* 引数数カウンタ計上 */
  200.     }
  201.  
  202.     /* 計上結果表示 */
  203.     printf(    "\nRESULT:\n"
  204.         " cmdline args    : %d\n"
  205.         " real args    : %d\n"
  206.         , argc, i
  207.     );
  208.  
  209.     return EXIT_SUCCESS;
  210. }
  211. #endif    /* defined(TEST_MAIN_DEFINE) */
  212.